#ifndef AC_COMMON_STRING_LIST_HPP_
#define AC_COMMON_STRING_LIST_HPP_

#include <cstdlib>

#include "common/string.hpp"
#include "common/string_enumeration.hpp"
#include "mutable_container.hpp"
#include "posib_err.hpp"

struct StringListNode
{
    String          data;
    StringListNode* next;
    StringListNode(ParmStr str, StringListNode* n = 0)
        : data(str), next(n)
    {
    }
};

class StringListEnumeration : public StringEnumeration
{
public:
    StringEnumeration* clone() const;
    void assign(const StringEnumeration* );

    StringListEnumeration(StringListNode* n)
        : n_(n)
    {}

    const char* next()
    {
        const char* temp;
        if (n_ == 0)
            temp = 0;
        else
        {
            temp = n_->data.c_str();
            n_ = n_->next;
        }
        return temp;
    }

    bool at_end() const
    {
        return n_ == 0;
    }

private:
    StringListNode* n_;
};

class StringList : public MutableContainer
{
private:
    StringListNode* first;
    StringListNode** find(ParmStr str);
    void copy(const StringList&);
    void destroy();

public:
    friend bool operator == (const StringList&, const StringList&);
    StringList() : first(0) {}
    StringList(const StringList& other)
    {
        copy(other);
    }

    StringList& operator = (const StringList& other)
    {
        destroy();
        copy(other);
        return *this;
    }

    virtual ~StringList()
    {
        destroy();
    }

    StringList* clone() const;
    void assign(const StringList*);

    PosibErr<bool> add(ParmStr);
    PosibErr<bool> remove(ParmStr);
    PosibErr<void> clear();

    StringEnumeration* elements() const;
    StringListEnumeration elements_obj() const
    {
        return StringListEnumeration(first);
    }

    bool empty() const
    {
        return first == 0;
    }

    unsigned int size() const {abort(); return 0;}

    StringList* new_string_list();
};

#endif  // AC_COMMON_STRING_LIST_HPP_
